package com.it.system.user.config;


import com.alibaba.fastjson.JSON;
import com.it.system.user.handler.LoginSuccessHandler;
import com.it.system.user.filter.JwtAuthenticationFilter;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@EnableWebSecurity
@Configuration
public class SecurityConfig {

    private static final Logger log = LoggerFactory.getLogger(SecurityConfig.class);

    /**
     * 提供密码编码器
     */
    @Bean
    public BCryptPasswordEncoder bCryptPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public AuthenticationManager authenticationManager(HttpSecurity http,
                                                       BCryptPasswordEncoder encoder,
                                                       UserDetailsService userDetailsService) throws Exception {
        return http.getSharedObject(AuthenticationManagerBuilder.class) //创建验证管理生成器
                .userDetailsService(userDetailsService)                 //设置登录验证逻辑
                .passwordEncoder(encoder)                               //设置密码编码器
                .and()
                .build();
    }

    @Resource
    private LoginSuccessHandler loginSuccessHandler;

    /**
     * 返回安全过滤器链，用于授权
     *
     * @param http
     * @return
     * @throws Exception
     */
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http, JwtAuthenticationFilter jwtAuthenticationFilter) throws Exception {
        log.info("正在配置安全过滤器链，JWT过滤器已注入: {}", jwtAuthenticationFilter);
        
        HttpSecurity httpSecurity = http.authorizeHttpRequests(a ->
                        a.requestMatchers("/login", "/logout").permitAll()  //放行一些url

                                .anyRequest().authenticated()                   //其它所有url，都要验证
                )
                .formLogin()
                .loginProcessingUrl("/login") //登录处理的url
                .successHandler(loginSuccessHandler) //登录成功后的处理
                .failureHandler((request, response, e) -> { //登录失败处理器
                    response.addHeader("Content-Type", "application/json;charset=UTF-8");
                    response.getWriter().write(JSON.toJSONString(ResponseEntity.ok("登录失败")));
                })
                .and()
                .exceptionHandling()                 //请求未经验证
                .authenticationEntryPoint((request, response, e) -> {
                    // 添加日志，记录请求路径和请求头
                    log.info("请求被拦截，路径: {}, Authorization: {}", request.getRequestURI(), request.getHeader("Authorization"));
                    response.addHeader("Content-Type", "application/json;charset=UTF-8");
                    response.getWriter().write(JSON.toJSONString(ResponseEntity.ok("没有登录")));
                })
                .and()
                .logout()                             //注销的相关配置
                .logoutUrl("/logout")
                .logoutSuccessHandler((request, response, authentication) -> {
                    response.addHeader("Content-Type", "application/json;charset=UTF-8");
                    response.getWriter().write(JSON.toJSONString(ResponseEntity.ok("注销成功")));
                })
                .clearAuthentication(true)                                //清除验证信息
                .and()
                .csrf()                                                   //关闭csrf
                .disable()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)     //session无状态策略
                .and()
                .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class); // 添加JWT过滤器
        
        log.info("安全过滤器链配置完成");
        return http.build();
    }

}
